package com.jixiang.goods.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jixiang.goods.dao.GsCardDao;
import com.jixiang.model.common.dtos.ResponseResult;
import com.jixiang.model.common.enums.AppHttpCodeEnum;
import com.jixiang.model.goods.dtos.CartDtos;
import com.jixiang.model.goods.entity.GsCard;
import com.jixiang.goods.service.GsCardService;
import com.jixiang.model.user.entity.UsUser;
import com.jixiang.utils.thread.UserThread;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.jixiang.common.constants.RedisConstants.*;

/**
 * (GsCard)表服务实现类
 *
 * @author makejava
 * @since 2023-11-04 00:09:09
 */
@Service("gsCardService")
public class GsCardServiceImpl extends ServiceImpl<GsCardDao, GsCard> implements GsCardService {

    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    RedissonClient redissonClient;
    @Override
    public ResponseResult appGetCart() {
        UsUser user = UserThread.getUser();
        if(user == null){
            return  ResponseResult.errorResult(AppHttpCodeEnum.TOKEN_EXPIRE);
        }

        String redisDate = stringRedisTemplate.opsForValue().get(REDIS_PREX_CARD+user.getId());
        if(StrUtil.isNotBlank(redisDate)){
            List<CartDtos> list = JSONUtil.toList(redisDate, CartDtos.class);
            return ResponseResult.okResult(list);
        }
        if(redisDate!=null){
            return ResponseResult.okResult(null);
        }
        List<CartDtos> cartDtosList = renewCard(user.getId());


        return ResponseResult.okResult(cartDtosList.isEmpty()?null:cartDtosList);
    }

    @Override
    public ResponseResult appAddCart(CartDtos cartDtos) {
        UsUser user = UserThread.getUser();
        if(user == null){
            return  ResponseResult.errorResult(AppHttpCodeEnum.TOKEN_EXPIRE);
        }
        GsCard gsCard = new GsCard();
        gsCard.setCount(cartDtos.getCount());
        gsCard.setGoodsId(cartDtos.getGoodsId());
        gsCard.setUserId(user.getId());
        gsCard.setSkusId(cartDtos.getSkuId());
        gsCard.setGoodsName(cartDtos.getName());
        gsCard.setPic(cartDtos.getPic());
        gsCard.setPrice(cartDtos.getPrice());
        gsCard.setSpecstext(cartDtos.getSpecsText());
        List<GsCard> list = query().eq("goods_id", gsCard.getGoodsId()).eq("user_id",gsCard.getUserId()).list();
        if(list==null || list.isEmpty()){
            boolean save = save(gsCard);
        }else {
            if(gsCard.getSkusId() == 0){
                GsCard gsCard1 = list.get(0);
                gsCard1.setCount(gsCard1.getCount()+gsCard.getCount());
                gsCard1.setCreateTime(new Date());
                boolean b = updateById(gsCard1);
            }else {
                List<GsCard> skulist = query().eq("goods_id", gsCard.getGoodsId()).eq("user_id",gsCard.getUserId()).eq("skus_id",gsCard.getSkusId()).list();
                if(skulist==null ||skulist.isEmpty()){
                    boolean save = save(gsCard);
                }else {
                    GsCard skucard = skulist.get(0);
                    skucard.setCount(skucard.getCount()+gsCard.getCount());
                    skucard.setCreateTime(new Date());
                    boolean b = updateById(skucard);
                }
            }
        }


        stringRedisTemplate.delete(REDIS_PREX_CARD+user.getId());
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<CartDtos> cartDtosList = renewCard(user.getId());
                if(cartDtosList!=null || !cartDtosList.isEmpty()){
                    System.out.println("更新缓存成功");
                }
            }
        },"renewCard").start();
        return ResponseResult.okResult("购物车添加成功");
    }

    @Override
    public ResponseResult appDelCart(CartDtos cartDtos) {
        UsUser user = UserThread.getUser();
        if(user == null){
            return  ResponseResult.errorResult(AppHttpCodeEnum.TOKEN_EXPIRE);
        }

            GsCard gsCard = query().eq("user_id", user.getId()).eq("goods_id", cartDtos.getGoodsId()).eq(cartDtos.getSkuId()!=0,"skus_id",cartDtos.getSkuId()).list().get(0);
            boolean b = removeById(gsCard);

        stringRedisTemplate.delete(REDIS_PREX_CARD+user.getId());
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<CartDtos> cartDtosList = renewCard(user.getId());
                if(cartDtosList!=null || !cartDtosList.isEmpty()){
                    System.out.println("更新缓存成功");
                }
            }
        },"renewCard").start();
        return ResponseResult.okResult("删除成功");

    }

    @Override
    public ResponseResult appMergeCartData(List<CartDtos> cartDtosList) {
        UsUser user = UserThread.getUser();
        if(user == null){
            return  ResponseResult.errorResult(AppHttpCodeEnum.TOKEN_EXPIRE);
        }
        cartDtosList.forEach(item -> {
            addCart(item,user.getId());
        });
        return ResponseResult.okResult("合并成功");
    }

    public void addCart (CartDtos cartDtos,Long userId) {

        GsCard gsCard = new GsCard();
        gsCard.setCount(cartDtos.getCount());
        gsCard.setGoodsId(cartDtos.getGoodsId());
        gsCard.setUserId(userId);
        gsCard.setSkusId(cartDtos.getSkuId());
        gsCard.setGoodsName(cartDtos.getName());
        gsCard.setPic(cartDtos.getPic());
        gsCard.setPrice(cartDtos.getPrice());
        gsCard.setSpecstext(cartDtos.getSpecsText());
        List<GsCard> list = query().eq("goods_id", gsCard.getGoodsId()).eq("user_id",gsCard.getUserId()).list();
        if(list==null || list.isEmpty()){
            boolean save = save(gsCard);
        }else {
            if(gsCard.getSkusId() == 0){
                GsCard gsCard1 = list.get(0);
                gsCard1.setCount(gsCard1.getCount()+gsCard.getCount());
                gsCard1.setCreateTime(new Date());
                boolean b = updateById(gsCard1);
            }else {
                List<GsCard> skulist = query().eq("goods_id", gsCard.getGoodsId()).eq("user_id",gsCard.getUserId()).eq("skus_id",gsCard.getSkusId()).list();
                if(skulist==null ||skulist.isEmpty()){
                    boolean save = save(gsCard);
                }else {
                    GsCard skucard = skulist.get(0);
                    skucard.setCount(skucard.getCount()+gsCard.getCount());
                    skucard.setCreateTime(new Date());
                    boolean b = updateById(skucard);
                }
            }
        }


        stringRedisTemplate.delete(REDIS_PREX_CARD+userId);
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<CartDtos> cartDtosList = renewCard(userId);
                if(cartDtosList!=null || !cartDtosList.isEmpty()){
                    System.out.println("更新缓存成功");
                }
            }
        },"renewCard").start();
    }

    List<CartDtos> renewCard(Long userId){
        RLock lock = redissonClient.getLock(REDIS_LOCK_CARD + userId.toString());
        List<CartDtos> cartDtosList = new LinkedList<CartDtos>();

        try {
            boolean tryLock = lock.tryLock(500, TimeUnit.MILLISECONDS);
            if(!tryLock){
                Thread.sleep(500);
                renewCard(userId);
            }
            List<GsCard> list = query().eq("user_id", userId).orderByDesc("create_time").list();
            if(list == null || list.isEmpty()){
                stringRedisTemplate.opsForValue().set(REDIS_PREX_CARD+userId.toString(),"",REDIS_EXPIRE_CARD,TimeUnit.HOURS);
            }else {
                List<CartDtos> collect = list.stream().map(item -> {
                    CartDtos cartDtos = new CartDtos();
                    cartDtos.setCartId(item.getId());
                    cartDtos.setGoodsId(item.getGoodsId());
                    cartDtos.setName(item.getGoodsName());
                    cartDtos.setPic(item.getPic());
                    cartDtos.setName(item.getGoodsName());
                    cartDtos.setPrice(item.getPrice());
                    cartDtos.setCount(item.getCount());
                    cartDtos.setSkuId(item.getSkusId());
                    cartDtos.setSpecsText(item.getSpecstext());
                    return cartDtos;
                }).collect(Collectors.toList());
                JSONArray jsonArray = JSONUtil.parseArray(collect);
                stringRedisTemplate.opsForValue().set(REDIS_PREX_CARD+userId.toString(),jsonArray.toString(),REDIS_EXPIRE_CARD,TimeUnit.HOURS);
                cartDtosList = collect;
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
        return cartDtosList;
    }


}

